#ifndef MENU_H
#define MENU_H

class Menu
{
        Lista<Rendeles*> _osszesrendelesek;
        Lista<Rendeles*> _rendelesek;
        Felhasznalo* _felhasznalo;
        Lista<Felhasznalo*> _felhasznalok;
        Lista<Tetel*>* _tetelek;
        std::set<std::string>* _kategoriak;

        int _maxid;
    public:
        Menu(Felhasznalo* felhasznalo, Lista<Felhasznalo*> felhasznalok)
        {
            _felhasznalo = felhasznalo;
            _tetelek = new Lista<Tetel*>();
            _kategoriak = new std::set<std::string>();
            std::cout << std::endl << "Udv " << _felhasznalo->GetName() << "!" << std::endl;
            _felhasznalok = felhasznalok;
            _maxid = 0;
            LoadTetelData();
            LoadRendelesData();
            WriteMainMenu();
            SaveRendelesData();
        }
        ~Menu()
        {
            SaveRendelesData();
        }
        void WriteMainMenu()
        {
            while(true)
            {
                std::cout << std::endl << "=== Menu ===" << std::endl;
                std::cout << "1. Uj rendeles" << std::endl;
                std::cout << "2. Korabbi rendelesek" << std::endl;
                std::cout << "0. Kilepes" << std::endl;
                std::string v = "";
                while (v != "0" && v != "1" && v != "2")
                {
                    std::cout << "Valasztas (1/2/0): ";
                    std::cin >> v;
                }
                if (v == "0") return;
                else if (v == "1")
                {
                    AddRendeles();
                }
                else if (v == "2")
                {
                    ModifyRendeles();
                }
            }
        }
        void ModifyRendeles()
        {
            if (_rendelesek.Size() > 0)
            {
                LoadTetelData();
                Iterator<Rendeles*> it = _rendelesek.Begin();
                int i = 1;
                while (it != _rendelesek.End())
                {
                    std::cout << i << " - Azonosito: " << (*it)->GetID() << ";" << std::endl;
                    ++it;
                    ++i;
                }
                i = _rendelesek.Size();
                int j = i+1;
                while (j<0 || j>i)
                {
                    std::cout << "Valasszon rendeles indexet (irjon 0-t visszavonashoz): ";
                    std::cin >> j;
                }
                if (j != 0)
                {
                    it = _rendelesek.Begin();
                    while (j>1)
                    {
                        --j;
                        ++it;
                    }
                    if ((*it)->GetPostazas() != 't')
                    {
                        (*it)->Edit();
                        if ((*it)->GetTorol()) _rendelesek.Remove(it);
                    }
                    else
                    {
                        std::cout << "A rendelest mar teljesitettuk, nem modosithato.";
                    }
                }
                SaveTetelData();
            }
        }
        void AddRendeles()
        {
            LoadTetelData();
            Rendeles* r = new Rendeles(++_maxid, *_felhasznalo, _tetelek, false, _kategoriak);
            if (r->GetTorol())
            {
                delete r;
            }
            else
            {
                _rendelesek.InsertLast(r);
                _osszesrendelesek.InsertLast(r);
                SaveTetelData();
            }
        }
        void LoadRendelesData()
        {
            _rendelesek.Clear();
            std::ifstream f("rendelesek.dat");
            if (f.fail())
            {
                std::cout << "Hianyzik a rendelesek.dat!" << std::endl;
                std::exit(3);
            }
            std::string tmp;
            while(std::getline(f, tmp))
            {
                int id, db;
                std::string nev, po;
                size_t pos = 0;
                std::string token;
                int i = 0;
                while ((pos = tmp.find(";")) != std::string::npos) {
                    token = tmp.substr(0, pos);
                    switch (i)
                    {
                        case 0 : id = atoi(token.c_str()); break;
                        case 1 : nev = token; break;
                        case 2 : db = atoi(token.c_str()); break;
                        case 3 : po = token; break;
                    }

                    tmp.erase(0, pos + 1);
                    ++i;
                }
                if (id > _maxid) _maxid = id;
                std::string tnev, tdb, tmegj;
                Iterator<Felhasznalo*> fh = _felhasznalok.Begin();
                while ((*fh)->GetName() != nev) ++fh;
                Rendeles* r = new Rendeles(id, *(*fh), _tetelek, true);
                for (int j=0; j<db; ++j)
                {
                    std::string t = "";
                    std::getline(f, tmp);
                    i=0;
                    pos = 0;
                    while ((pos = tmp.find(";")) != std::string::npos) {
                        token = tmp.substr(0, pos);
                        switch (i)
                        {
                            case 0 : tnev = token; break;
                            case 1 : tdb = token; break;
                            case 2 : tmegj = token; break;
                        }
                        tmp.erase(0, pos + 1);
                        ++i;
                    }
                    Iterator<Tetel*> it = _tetelek->Begin();
                    while (it != _tetelek->End() && (*it)->GetName() != tnev)
                    {
                        ++it;
                    }
                    if ((*it)->GetT() == "t")
                    {
                        r->AddTetel(new Termek(tnev, (*it)->GetCategory(), (*it)->GetValue(), atoi(tdb.c_str())));
                    }
                    else if ((*it)->GetT() == "sz")
                    {
                        r->AddTetel(new Szolgaltatas(tnev, (*it)->GetCategory(), (*it)->GetValue(), atoi(tdb.c_str()), tmegj));
                    }
                }
                _osszesrendelesek.InsertLast(r);
                if (nev == _felhasznalo->GetName())
                {
                    _rendelesek.InsertLast(r);
                }
            }
            f.close();
        }
        void SaveRendelesData()
        {
            std::ofstream f("rendelesek.dat");
            Iterator<Rendeles*> it =  _osszesrendelesek.Begin();
            while (it != _osszesrendelesek.End())
            {
                f << (*it)->GetID() << ";" << (*it)->GetFelhasznalo().GetName() << ";" << (*it)->GetKosar()->Size() << ";" << (*it)->GetPostazas() << ";" << std::endl;
                Iterator<Tetel*> kit = (*it)->GetKosar()->Begin();
                while (kit != (*it)->GetKosar()->End())
                {
                    if ((*kit)->GetT() == "t")
                    {
                        f << (*kit)->GetName() << ";" << (*kit)->GetQuantity() << ";" << std::endl;
                    }
                    else if ((*kit)->GetT() == "sz")
                    {
                        f << (*kit)->GetName() << ";" << (*kit)->GetQuantity() << ";" << (*kit)->GetComment() << ";"<< std::endl;
                    }
                    ++kit;
                }
                ++it;
            }
            f.close();
        }
        void LoadTetelData()
        {
            _tetelek->Clear();
            _kategoriak->clear();
            std::ifstream f("tetelek.dat");
            if (f.fail())
            {
                std::cout << "Hianyzik a tetelek.dat!" << std::endl;
                std::exit(2);
            }
            std::string tmp;
            while(std::getline(f, tmp))
            {
                int id;
                std::string t, nev, kat, ar, dbe;
                size_t pos = 0;
                std::string token;
                int i = 0;
                while ((pos = tmp.find(";")) != std::string::npos) {
                    token = tmp.substr(0, pos);
                    switch (i)
                    {
                        case 0 : t = token; break;
                        case 1 : nev = token; break;
                        case 2 : kat = token; break;
                        case 3 : ar = token; break;
                        case 4 : dbe = token; break;
                    }
                    tmp.erase(0, pos + 1);
                    ++i;
                }
                _kategoriak->insert(kat);
                if (t == "t")
                {
                    _tetelek->InsertLast(new Termek(nev, kat, atoi(ar.c_str()), atoi(dbe.c_str())));
                }
                else if (t == "sz")
                {
                    _tetelek->InsertLast(new Szolgaltatas( nev, kat, atoi(ar.c_str()), atoi(dbe.c_str())));
                }
            }
            f.close();
        }
        void SaveTetelData()
        {
            std::ofstream f("tetelek.dat");
            Iterator<Tetel*> it =  _tetelek->Begin();
            while (it != _tetelek->End())
            {
                f << (*(*it)).GetT() << ";" << (*it)->GetName() << ";" << (*it)->GetCategory() << ";" << (*it)->GetValue() << ";" << (*it)->GetQuantity() << ";" << std::endl;
                ++it;
            }
            f.close();
        }

};

#endif
